package com.okilo.online.app.act

import android.annotation.SuppressLint
import android.content.Context
import android.content.Intent
import android.content.IntentFilter
import android.os.Build
import android.os.CountDownTimer
import android.text.Editable
import android.text.TextWatcher
import android.view.Gravity
import android.view.View
import android.view.WindowManager
import android.widget.ImageView
import androidx.lifecycle.lifecycleScope
import androidx.recyclerview.widget.DefaultItemAnimator
import androidx.recyclerview.widget.GridLayoutManager
import com.google.android.gms.auth.api.phone.SmsRetriever
import com.okilo.online.app.R
import com.okilo.online.app.base.app.OkiloActStackManager
import com.okilo.online.app.common.OkiloComAct
import com.okilo.online.app.configs.OkiloConfigs
import com.okilo.online.app.databinding.OkiloActVerifyMobileBinding
import com.okilo.online.app.event.OkiloEventData
import com.okilo.online.app.event.OkiloEventPointType
import com.okilo.online.app.event.room.OkiloPointManager
import com.okilo.online.app.tools.apt.OkiloOnSingleClickListener
import com.okilo.online.app.tools.decoration.GridSpacingItemDecoration
import com.okilo.online.app.tools.helper.OkiloConfigProcessHp
import com.okilo.online.app.tools.log.OkiloLog
import com.okilo.online.app.tools.receiver.OkiloVerifyMobileBroadReceiver
import com.okilo.online.app.tools.shared.OkiloSharedHp
import com.okilo.online.app.tools.shared.OkiloSharedKey
import com.okilo.online.app.apt.OkiloVerifyMobileTypeApt
import com.okilo.online.app.dialog.OkiloSubSuccessDlog
import com.okilo.online.app.dialog.OkiloTipsDlog
import com.okilo.online.app.pet.OkiloUserPet
import com.okilo.online.app.pet.view.IOkiloUser
import com.okilo.online.app.weight.font.OkiloRbtMediumEditText
import com.okilo.online.app.weight.font.OkiloRbtSemiBoldButton
import com.okilo.online.app.weight.pickerview.builder.TimePickerBuilder
import com.okilo.online.app.weight.pickerview.listener.OnTimeSelectListener
import com.okilo.online.app.weight.pickerview.view.TimePickerView
import kotlinx.coroutines.delay
import kotlinx.coroutines.launch
import org.json.JSONObject
import java.text.SimpleDateFormat
import java.util.Calendar
import java.util.Date

/**
 * OkiloLoan
 * @Author wwdeng
 * @CreateTime: 2024/11/11 16:41
 * @Annotation：手机号验证页面
 *
 * isEdit: 控制号码编辑状态。true：不可切换type，不可获取验证码，不可点击下一步
 *
 *
 *
 */
class OkiloVerifyMobileAct: OkiloComAct(), IOkiloUser.IOkiloVerifyMobile{
    private var _binding: OkiloActVerifyMobileBinding? = null

    private var sendSuccessDialog: OkiloSubSuccessDlog? = null
    private var smsBroadcastReceiver: OkiloVerifyMobileBroadReceiver? = null

    private val SMS_CONSENT_REQUEST = 200

    //等待时长
    private var countdownTimer: OkiloVerifyMobileCountDownTimer? = null
    private var countdown = 60
    //电话号码是否在编辑状态
    private var isMobileEdit = false

    private var typeApt: OkiloVerifyMobileTypeApt? = null
    //选择类型  SMS  、 WHATSAPP
    private var selectType = ""
    //是否需要选择出生日期
    private var needSubmitBirthDay = "NO"
    //出生日期选择
    private var okiloBirthDateView: TimePickerView? = null

    private var userPet: OkiloUserPet? = null

    companion object {
        fun start(context: Context) {
            //当前栈顶是 手机号校验页面 不重复跳转
            if (OkiloActStackManager.isCurrentActivity(OkiloVerifyMobileAct::class.java)){
                return
            }
            val intent = Intent(context, OkiloVerifyMobileAct::class.java)
            context.startActivity(intent)
        }
    }
    override val pageName: String = "CheckMobile_Page"

    override fun createOkiloContentView(): View? {
        _binding = OkiloActVerifyMobileBinding.inflate(layoutInflater)
        return _binding?.root
    }

    override fun initializeOkiloViews() {
        setBackExit(true)
        getTitleBarManager()
            .setTitleBarVisibility(View.VISIBLE)
            .setBackButtonVisibility(View.GONE)
            .setTitleVisibility(View.GONE)
            .setRightButtonIcon(R.mipmap.okilo_root_customer_icon)
            .setRootBackgroundColor(getColor(R.color.okilo_color_white))

        initOkiloVerifyMobileRefreshView()
        initOkiloVerifyMobileTypeGridView()
        sOkiloVerifyMobileTypeView()
        sOkiloVerifyMobileCheckCodeWrongType(false)

        SmsRetriever.getClient(this).startSmsUserConsent(null)
        registerSMSBroadcastReceiver()
    }

    override fun setupOkiloEventListeners() {
        super.setupOkiloEventListeners()
        _binding?.okiloVerifyMobileCodeEdit?.addTextChangedListener(object : TextWatcher {
            override fun beforeTextChanged(s: CharSequence?, start: Int, count: Int, after: Int) {
            }
            override fun onTextChanged(s: CharSequence?, start: Int, before: Int, count: Int) {
            }
            override fun afterTextChanged(s: Editable?) {
                _binding?.okiloVerifyMobileButtonSubmit?.isEnabled = selectType.isNotEmpty() && gOkiloVerifyCode().isNotEmpty()
                sOkiloVerifyMobileCheckCodeWrongType(false)
            }
        })
        _binding?.okiloVerifyMobileCodeEdit?.setInputFocusChangeListener(object : OkiloRbtMediumEditText.IInputFocusChangeListener{
            override fun onFocusChange(v: View?, hasFocus: Boolean) {
                sOkiloVerifyMobileCheckCodeWrongType(false)
            }
            override fun onCompleteAction(v: View?, remark: String?) {
            }
        })
        _binding?.okiloVerifyMobileEdit?.addTextChangedListener(object : TextWatcher {
            override fun beforeTextChanged(s: CharSequence?, start: Int, count: Int, after: Int) {
            }
            override fun onTextChanged(s: CharSequence?, start: Int, before: Int, count: Int) {
            }
            @SuppressLint("SetTextI18n")
            override fun afterTextChanged(s: Editable?) {
                _binding?.okiloVerifyMobileEditConfirm?.isEnabled = gOkiloVerifyMobile().isNotEmpty()
                _binding?.okiloVerifyMobileText?.text = "${_binding?.okiloVerifyMobileZoneCodeText?.text} ${gOkiloVerifyMobile()}"
            }
        })

        /**
         * 发送验证码
         */
        _binding?.okiloVerifyMobileButtonSend?.setOnClickListener(object : OkiloOnSingleClickListener(){
            override fun onSingleClick(v: View?) {
                if (selectType.isEmpty() || gOkiloVerifyMobile().isEmpty() || isMobileEdit){
                    return
                }
                //发送验证，埋点增加手机号
                addEventPointRequestAction(OkiloEventPointType.OKILO_CLICK_TRACK.VERIFICATION_SEND_CODE,gOkiloVerifyMobile())
                showOkiloLoading()
                userPet?.gOkiloUserVerifyMobileSendCodeRequest(this@OkiloVerifyMobileAct)
            }
        })
        //手机号编辑
        _binding?.okiloVerifyMobileEditIcon?.setOnClickListener(object : OkiloOnSingleClickListener(){
            override fun onSingleClick(v: View?) {
                isMobileEdit = true
                sOkiloVerifyMobileTypeView()
            }
        })
        //手机号编辑确认
        _binding?.okiloVerifyMobileEditConfirm?.setOnClickListener(object : OkiloOnSingleClickListener(){
            @SuppressLint("SetTextI18n")
            override fun onSingleClick(v: View?) {
                if (gOkiloVerifyMobile().isEmpty()){
                    return
                }
                isMobileEdit = false
                _binding?.okiloVerifyMobileText?.text = "${_binding?.okiloVerifyMobileZoneCodeText?.text} ${gOkiloVerifyMobile()}"
                sOkiloVerifyMobileTypeView()
            }
        })
        //提交
        _binding?.okiloVerifyMobileButtonSubmit?.setOnClickListener(object : OkiloOnSingleClickListener(){
            override fun onSingleClick(v: View?) {
                if (gOkiloVerifyMobile().isEmpty() || gOkiloVerifyCode().isEmpty()){
                    _binding?.okiloVerifyMobileButtonSubmit?.isEnabled = false
                    return
                }
                addEventPointRequestAction(OkiloEventPointType.OKILO_CLICK_TRACK.VERIFICATION_CONTINUE,"${gOkiloVerifyCode()}##${gOkiloVerifyMobile()}")
                // TODO: 校验手机号点完成 需上报所有埋点
                OkiloPointManager.getInstance().manualReport()

                subOkiloVerifyMobileCodeAction()
            }
        })
    }

    @SuppressLint("SetTextI18n")
    override fun loadOkiloData() {
        if (userPet == null){
            userPet = OkiloUserPet(this)
        }
        val zoneCode = OkiloSharedHp.gOkiloSharedString(OkiloSharedKey.SP_OKILO_TIMEZONE_CODE)
        val mobile = OkiloSharedHp.gOkiloSharedString(OkiloSharedKey.SP_OKILO_MOBILE)
        _binding?.okiloVerifyMobileZoneCodeText?.text = "+$zoneCode"
        _binding?.okiloVerifyMobileText?.text = "+$zoneCode $mobile"
        _binding?.okiloVerifyMobileEdit?.setText(mobile)

        _binding?.okiloVerifyMobileButtonSend?.text = getString(R.string.okilo_btn_send)
        _binding?.okiloVerifyMobileButtonSend?.isEnabled = true
        _binding?.okiloVerifyMobileButtonSend?.setTextColor(getColor(R.color.okilo_color_white))
        _binding?.okiloVerifyMobileButtonSend?.setBackgroundResource(R.drawable.okilo_check_mobile_btn_send_pressed_bg)

        var isAddSelected = false
        val typeList = arrayListOf<JSONObject>()
        if (OkiloConfigProcessHp.iOkiloCheckSmsFlag()){
            val item = JSONObject()
            item.put("type","SMS")
            item.put("title",getString(R.string.okilo_check_mobile_type_sms))
            isAddSelected = true
            item.put("isSelected",true)
            item.put("normalIcon", R.mipmap.okilo_check_mobile_sms_normal_icon)
            item.put("selectIcon", R.mipmap.okilo_check_mobile_sms_select_icon)
            typeList.add(item)
            sOkiloVerifyMobileCheckType(item.optString("type"))
        }
        if (OkiloConfigProcessHp.iOkiloCheckWhatsAppFlag()){
            val item = JSONObject()
            item.put("type","WHATSAPP")
            item.put("title",getString(R.string.okilo_check_mobile_type_whatsapp))
            item.put("normalIcon", R.mipmap.okilo_check_mobile_whatsapp_normal_icon)
            item.put("selectIcon", R.mipmap.okilo_check_mobile_whatsapp_select_icon)
            if (!isAddSelected){
                item.put("isSelected",true)
                sOkiloVerifyMobileCheckType(item.optString("type"))
            }
            typeList.add(item)
        }
        typeApt?.data = typeList

        sOkiloVerifyMobileTipsDialog()
    }

    /**
     * 注册SMS广播接收
     */
    private fun registerSMSBroadcastReceiver(){
        // 2 register receiver
        val intentFilter = IntentFilter(SmsRetriever.SMS_RETRIEVED_ACTION)
        smsBroadcastReceiver = OkiloVerifyMobileBroadReceiver {
            startActivityForResult(it, SMS_CONSENT_REQUEST)
        }
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) {
            // Android 13 及以上版本使用 receiverFlags 参数
            registerReceiver(smsBroadcastReceiver, intentFilter, SmsRetriever.SEND_PERMISSION, null,
                RECEIVER_EXPORTED
            )// 指定导出标志
        } else if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
            // Android 8.0 到 Android 12 版本使用带权限的 registerReceiver()
            registerReceiver(smsBroadcastReceiver, intentFilter, SmsRetriever.SEND_PERMISSION, null)
        } else {
            // Android 8.0 以下版本，只使用 receiver 和 intentFilter 参数
            registerReceiver(smsBroadcastReceiver, intentFilter)
        }
    }

    override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
        super.onActivityResult(requestCode, resultCode, data)
        if (requestCode == SMS_CONSENT_REQUEST) {
            if (resultCode == RESULT_OK && data != null) {
                // 读取短信内容
                val message = data.getStringExtra(SmsRetriever.EXTRA_SMS_MESSAGE)
                OkiloLog.i("Sms content: $message")

                // 提取otp
                val code = extractFirstNumber(message)
                OkiloLog.i("Sms code: $code")
                if (code != null){
                    _binding?.okiloVerifyMobileCodeEdit?.setText(code)
                }
            } else {
                // 用户不同意或没收到待
                OkiloLog.e("User canceled or no message received")
            }
        }
    }

    /* 初始化刷新 */
    private fun initOkiloVerifyMobileRefreshView() {
        _binding?.okiloVerifyMobileRefreshLayout?.setColorSchemeResources(
            R.color.okilo_color_theme,
            R.color.okilo_color_ff6200ee)
        _binding?.okiloVerifyMobileRefreshLayout?.setOnRefreshListener {
            publishEventData(OkiloEventData(OkiloEventData.TYPE.OKILO_PROCESS_REFRESH))
        }
    }

    /**
     * 初始化手机号校验类型GridView
     */
    @SuppressLint("NotifyDataSetChanged")
    private fun initOkiloVerifyMobileTypeGridView(){
        val binding = _binding ?: return

        val layoutManager = GridLayoutManager(this, 2)
        binding.okiloVerifyMobileTypeGridView.layoutManager = layoutManager
        val itemDecoration = GridSpacingItemDecoration.Companion.create(
            spanCount = 2,
            spacingDp = 13,
            context = this,
            includeEdge = false,
            includeTop = true,
            includeBottom = false,
            topSpacingType = GridSpacingItemDecoration.TopSpacingType.BETWEEN_ROWS_ONLY
        )
        binding.okiloVerifyMobileTypeGridView.addItemDecoration(itemDecoration)
        typeApt = OkiloVerifyMobileTypeApt(binding.okiloVerifyMobileTypeGridView)
        binding.okiloVerifyMobileTypeGridView.adapter = typeApt
        binding.okiloVerifyMobileTypeGridView.itemAnimator = DefaultItemAnimator()
        typeApt?.setOnItemChildClickListener{ _, childView, position ->
            val adapter = typeApt ?: return@setOnItemChildClickListener
            val item = adapter.getItem(position)
            if (item.optBoolean("isSelected",false) || isMobileEdit){
                return@setOnItemChildClickListener
            }
            adapter.data.forEach {
                it.put("isSelected",false)
            }
            item.put("isSelected",true)
            adapter.notifyDataSetChanged()

            val type = item.optString("type")
            sOkiloVerifyMobileCheckType(type)
            addEventPointRequestAction(String.Companion.format(OkiloEventPointType.OKILO_CLICK_TRACK.VERIFICATION_TYPE,type))
        }
    }

    /**
     * 获取登录手机号
     */
    override fun gOkiloLoginMobile(): String {
        return OkiloConfigs.gOkiloLoginMobile()
    }

    /**
     * 获取手机号
     */
    override fun gOkiloVerifyMobile(): String {
        return _binding?.okiloVerifyMobileEdit?.text.toString().trim()
    }

    /**
     * 获取验证码
     */
    override fun gOkiloVerifyCode(): String {
        return _binding?.okiloVerifyMobileCodeEdit?.text.toString().trim()
    }

    /**
     * 获取校验类型
     * SMS 、 WHATSAPP
     */
    override fun gOkiloVerifyType(): String {
        return selectType
    }

    /**
     * 是否需要选择出生日期
     * 发送验证码接口会返回
     */
    override fun gOkiloVerifyMobileNeedSubmitBirthDay(): String {
        return needSubmitBirthDay
    }

    /**
     * 验证码发送成功
     * 当为directLoginFlag="YES"时可以跳过，直接调用流程接口，根据流程步骤whatsappFlag标识走
     */
    override fun sOkiloVerifyMobileSendSuccess(directLoginFlag: String) {
        when(directLoginFlag){
            "YES" -> {
                sOkiloVerifyMobileSuccess()
            }
            else -> {
                startOkiloVerifyMobileTimer()
            }
        }
    }

    /**
     * 设置是否需要选择出生日期
     */
    override fun sOkiloVerifyMobileCheckBirthDate(isNeed: String) {
        this.needSubmitBirthDay = isNeed
    }

    /**
     * 手机号校验成功
     */
    override fun sOkiloVerifyMobileSuccess() {
        OkiloSharedHp.sOkiloSharedData(OkiloSharedKey.SP_OKILO_MOBILE, gOkiloVerifyMobile())
        publishEventData(OkiloEventData(OkiloEventData.TYPE.OKILO_PROCESS_REFRESH))
        if (countdownTimer != null){
            countdownTimer?.cancel()
        }
        finish()
    }

    /**
     * 校验失败
     */
    override fun sOkiloVerifyMobileFailed() {
        sOkiloVerifyMobileCheckCodeWrongType(true)
    }

    /**
     * 校验验证码
     */
    fun subOkiloVerifyMobileCodeAction(submitBirthDay: String = ""){
        //需要提交出生日期
        if (needSubmitBirthDay == "YES" && submitBirthDay.isEmpty()){
            sOkiloVerifyMobileNeedChooseBirthdayDialog()
            return
        }
        showOkiloLoading()
        userPet?.checkOkiloUserVerifyMobileRequest(submitBirthDay,this)
    }

    /**
     * 切换校验类型
     */
    private fun sOkiloVerifyMobileCheckType(type: String){
        if (selectType == type){
            return
        }
        selectType = type
        when(type){
            "SMS" -> {
                _binding?.okiloVerifyMobileTypeTitle?.text = String.format(getString(R.string.okilo_check_mobile_type),getString(
                    R.string.okilo_check_mobile_type_sms))
            }
            else -> {
                _binding?.okiloVerifyMobileTypeTitle?.text = String.format(getString(R.string.okilo_check_mobile_type),getString(
                    R.string.okilo_check_mobile_type_whatsapp))
            }
        }
        _binding?.okiloVerifyMobileButtonSubmit?.isEnabled = gOkiloVerifyCode().isNotEmpty()
    }

    /**
     * 切换是否修改手机号View
     */
    private fun sOkiloVerifyMobileTypeView(){
        val binding = _binding ?: return
        //是否允许修改手机号码
        if (!OkiloConfigProcessHp.iOkiloMobileEditFlag()){
            binding.okiloVerifyMobileLayout.visibility = View.VISIBLE
            binding.okiloVerifyMobileEditIcon.visibility = View.INVISIBLE
            binding.okiloVerifyMobileEditLayout.visibility = View.GONE
            return
        }
        when(isMobileEdit){
            true -> {
                binding.okiloVerifyMobileLayout.visibility = View.GONE
                binding.okiloVerifyMobileEditLayout.visibility = View.VISIBLE
                onShowSoftInput(binding.okiloVerifyMobileEdit)
                binding.okiloVerifyMobileEdit.setSelection(gOkiloVerifyMobile().length)
            }
            else -> {
                binding.okiloVerifyMobileLayout.visibility = View.VISIBLE
                binding.okiloVerifyMobileEditIcon.visibility = View.VISIBLE
                binding.okiloVerifyMobileEditLayout.visibility = View.GONE
            }
        }
    }

    /**
     * 是否显示验证码错误提示
     */
    private fun sOkiloVerifyMobileCheckCodeWrongType(isError: Boolean){
        val binding = _binding ?: return
        when(isError){
            true -> {
                binding.okiloVerifyMobileCodeEdit.setTextColor(getColor(R.color.okilo_color_fff0492b))
                binding.okiloVerifyMobileCodeEdit.setBackgroundResource(R.drawable.okilo_check_mobile_edit_code_error_bg)
                binding.okiloVerifyMobileCodeWrongLayout.visibility = View.VISIBLE
            }
            else -> {
                binding.okiloVerifyMobileCodeEdit.setTextColor(getColor(R.color.okilo_color_black))
                if (binding.okiloVerifyMobileCodeEdit.hasFocus()){
                    binding.okiloVerifyMobileCodeEdit.setBackgroundResource(R.drawable.okilo_check_mobile_edit_code_select_bg)
                } else {
                    binding.okiloVerifyMobileCodeEdit.setBackgroundResource(R.drawable.okilo_check_mobile_edit_code_normal_bg)
                }
                binding.okiloVerifyMobileCodeWrongLayout.visibility = View.INVISIBLE
            }
        }
    }

    /**
     * 需要选择出生日期
     */
    private fun sOkiloVerifyMobileNeedChooseBirthdayDialog() {
        if(okiloBirthDateView == null){
            //时间可选范围18-100岁
            //当前日期
            val curtDate = Calendar.getInstance()
            val startDate = Calendar.getInstance()
            startDate.timeInMillis = curtDate.timeInMillis
            startDate.add(Calendar.YEAR,-100)

            val endDate = Calendar.getInstance()
            endDate.timeInMillis = curtDate.timeInMillis
            endDate.add(Calendar.YEAR,-18)

            okiloBirthDateView = TimePickerBuilder(this, object : OnTimeSelectListener {
                override fun onTimeSelect(date: Date?, v: View?) {
                }

                @SuppressLint("SimpleDateFormat")
                override fun onTimeSelectString(date: Date?, showDate: String?) {
                    date?.let {
                        val value = SimpleDateFormat("yyyy-MM-dd").format(it)
                        subOkiloVerifyMobileCodeAction(value)
                    }
                }
            })
                .setDate(endDate) //默认选中
                .setRangDate(startDate, endDate) //可选择时间范围
                .setLayoutRes(R.layout.okilo_dlog_birthdate) { v ->
                    val ivClose = v.findViewById<ImageView>(R.id.okiloBirthCloseIcon)
                    ivClose.setOnClickListener {
                        okiloBirthDateView?.dismiss()
                    }
                    //确定
                    val btnConfirm = v.findViewById<OkiloRbtSemiBoldButton>(R.id.okiloBirthButtonConfirm)
                    btnConfirm.setOnClickListener {
                        okiloBirthDateView?.returnData()
                        okiloBirthDateView?.dismiss()
                    }
                }
                .isDialog(true)
                .setContentTextSize(16)
                .setType(booleanArrayOf(true, true, true, false, false, false))
                .setLabel("", "", "", "", "", "")
                .setLineSpacingMultiplier(3.5f)
                .setTextXOffset(65, 65, 65, 65, 65, 65)
                .isCenterLabel(false)//是否只显示中间选中项的label文字，false则每项item全部都带有label。
                .setTextColorCenter(getColor(R.color.okilo_color_ff0c092a)) //设置选中项文字颜色
                .setTextColorOut(getColor(R.color.okilo_color_ffc8c8c8))//默认颜色
                .setBgColor(getColor(R.color.okilo_color_transparent))
                .isAlphaGradient(true)
                .setItemVisibleCount(3)
                .isCyclic(true)
                .setDividerColor(getColor(R.color.okilo_color_transparent))
                .build()
            val dialog = okiloBirthDateView?.dialog
            dialog?.let {
                val dialogWindow = it.window
                if (dialogWindow != null) {
                    val params = dialogWindow.attributes
                    params.width = WindowManager.LayoutParams.MATCH_PARENT
                    params.height = WindowManager.LayoutParams.WRAP_CONTENT
                    dialogWindow.attributes = params
                    dialogWindow.setWindowAnimations(R.style.dialog_slide_anim) //修改动画样式
                    dialogWindow.setGravity(Gravity.CENTER)
                    dialogWindow.setDimAmount(0.3f)
                }
            }
        }
        okiloBirthDateView?.show()
    }

    /**
     * 发送成功提示
     */
    private fun sOkiloVerifyMobileSendCodeSuccessDialog(){
        if (sendSuccessDialog == null){
            sendSuccessDialog = OkiloSubSuccessDlog(this, "SendCode_Success")
            sendSuccessDialog?.setCancelable(true)
            sendSuccessDialog?.setCanceledOnTouchOutside(false)
        }
        sendSuccessDialog?.show()
        sendSuccessDialog?.setTipsSuccessText(getString(R.string.okilo_check_mobile_send_success_tips))
        lifecycleScope.launch {
            delay(1500)
            // 检查 Activity 状态
            if (isFinishing || isDestroyed) {
                return@launch
            }
            safeDismissSuccessDialog()

            _binding?.let {
                //发送验证码成功，验证码输入框获得焦点
                onShowSoftInput(it.okiloVerifyMobileCodeEdit)
            }
        }
    }

    /**
     * 安全退出验证码发送成功dialog
     */
    private fun safeDismissSuccessDialog() {
        try {
            if (sendSuccessDialog != null && sendSuccessDialog!!.isShowing && !isFinishing) {
                sendSuccessDialog?.dismiss()
            }
        } catch (e: IllegalArgumentException) {
            // 安全处理异常
            OkiloLog.e( "Dialog dismiss error: ${e.message}")
        } catch (e: Exception) {
            OkiloLog.e( "Unexpected error: ${e.message}")
        } finally {
            sendSuccessDialog = null
        }
    }

    /**
     * 提示dialog
     */
    private fun sOkiloVerifyMobileTipsDialog(){
        val tipsDialog = OkiloTipsDlog(this, pageName)
        tipsDialog.setCancelable(true)
        tipsDialog.setCanceledOnTouchOutside(true)
        tipsDialog.show()
        tipsDialog.sOkiloDlogTipsTitleText(getString(R.string.okilo_dlog_notice))
        tipsDialog.sOkiloDlogTipsMsgText(getString(R.string.okilo_check_mobile_dialog_tips))
        tipsDialog.sOkiloDlogTipsButtonConfirmText(getString(R.string.okilo_check_mobile_dialog_understand))
        tipsDialog.iOkiloDlogTipsDoubleButton(false)
    }

    /**
     * 提取连续的数字
     */
    private fun extractFirstNumber(input: String?): String? {
        if(input.isNullOrBlank()) return ""

        val regex = "\\d+".toRegex()
        return regex.find(input)?.value
    }

    class OkiloVerifyMobileCountDownTimer(private val act: OkiloVerifyMobileAct, millisInFuture: Int): CountDownTimer(millisInFuture.toLong(), 1000) {
        override fun onTick(millisUntilFinished: Long) {
            // 这里每隔一段时间（定时器间隔）会被调用
            // 可以在这里更新UI，显示剩余时间
            act.countdown = (millisUntilFinished / 1000).toInt()
            act.sOkiloVerifyMobileCountdownText()
        }
        override fun onFinish() {
            // 倒计时完成时被调用
            act.sOkiloVerifyMobileCountdownFinish()
        }
    }

    /**
     * 倒计时
     */
    @SuppressLint("SetTextI18n")
    private fun sOkiloVerifyMobileCountdownText(){
        _binding?.okiloVerifyMobileButtonSend?.text = "${countdown}s"
    }

    /**
     * 倒计时完成
     */
    private fun sOkiloVerifyMobileCountdownFinish(){
        countdown = 60
        _binding?.okiloVerifyMobileButtonSend?.text = getString(R.string.okilo_btn_resend)
        _binding?.okiloVerifyMobileButtonSend?.isEnabled = true
        _binding?.okiloVerifyMobileButtonSend?.setTextColor(getColor(R.color.okilo_color_ffebab6b))
        _binding?.okiloVerifyMobileButtonSend?.setBackgroundResource(R.drawable.okilo_check_mobile_btn_resend_pressed_bg)
        sOkiloVerifyMobileTypeView()
    }

    /**
     * 启动倒计时
     */
    @SuppressLint("SetTextI18n")
    private fun startOkiloVerifyMobileTimer() {
        val binding = _binding ?: return
        if (isFinishing || isDestroyed){
            return
        }
        sOkiloVerifyMobileSendCodeSuccessDialog()
        //随机 60秒 等待时长
        countdown = 60
        binding.okiloVerifyMobileButtonSend.text = "${countdown}s"
        binding.okiloVerifyMobileButtonSend.isEnabled = false
        binding.okiloVerifyMobileButtonSend.setTextColor(getColor(R.color.okilo_color_ffd2d2d2))
        binding.okiloVerifyMobileButtonSend.setBackgroundResource(R.drawable.okilo_check_mobile_btn_send_disabled_bg)
        //手机号码输入框变成不可编辑状态
        binding.okiloVerifyMobileLayout.visibility = View.VISIBLE
        binding.okiloVerifyMobileEditIcon.visibility = View.INVISIBLE
        binding.okiloVerifyMobileEditLayout.visibility = View.GONE

        if (countdownTimer == null){
            countdownTimer = OkiloVerifyMobileCountDownTimer(this, countdown * 1000)
        }
        countdownTimer?.start()
    }

    override fun onOkiloPublishEvent(event: OkiloEventData) {
        super.onOkiloPublishEvent(event)
        when(event.eventType){
            OkiloEventData.TYPE.OKILO_PROCESS_REFRESHED -> {
                hideOkiloLoading()
                //需要校验 WhatsApp 或 SMS
                if (!OkiloConfigProcessHp.iOkiloCheckWhatsAppFlag() && !OkiloConfigProcessHp.iOkiloCheckSmsFlag()){
                    //校验成功
                    sOkiloVerifyMobileSuccess()
                }
            }
            OkiloEventData.TYPE.OKILO_HTTP_REQUEST_ERROR -> {
                hideOkiloLoading()
            }
            else -> {

            }
        }
    }

    override fun hideOkiloLoading() {
        super.hideOkiloLoading()
        _binding?.okiloVerifyMobileRefreshLayout?.isRefreshing = false
    }

    override fun onDestroy() {
        super.onDestroy()
        if (countdownTimer != null){
            countdownTimer?.cancel()
            countdownTimer = null
        }
        if (smsBroadcastReceiver != null){
            unregisterReceiver(smsBroadcastReceiver)
        }
        _binding = null
    }
}